<?php

namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;

class CacheService
{
    /**
     * 缓存键前缀
     */
    const PREFIX = 'judian:';
    const USER_PREFIX = 'user:';
    const ROOM_PREFIX = 'room:';
    const DISH_PREFIX = 'dish:';
    const ORDER_PREFIX = 'order:';

    /**
     * 缓存时间（秒）
     */
    const TTL_SHORT = 300;      // 5分钟
    const TTL_MEDIUM = 1800;    // 30分钟
    const TTL_LONG = 3600;      // 1小时
    const TTL_VERY_LONG = 86400; // 24小时

    /**
     * 获取缓存
     */
    public function get(string $key, $default = null)
    {
        return Cache::get($this->getKey($key), $default);
    }

    /**
     * 设置缓存
     */
    public function put(string $key, $value, int $ttl = self::TTL_MEDIUM): bool
    {
        return Cache::put($this->getKey($key), $value, $ttl);
    }

    /**
     * 永久缓存
     */
    public function forever(string $key, $value): bool
    {
        return Cache::forever($this->getKey($key), $value);
    }

    /**
     * 删除缓存
     */
    public function forget(string $key): bool
    {
        return Cache::forget($this->getKey($key));
    }

    /**
     * 清空所有缓存
     */
    public function flush(): bool
    {
        return Cache::flush();
    }

    /**
     * 用户相关缓存
     */
    public function getUser(int $userId)
    {
        return $this->get(self::USER_PREFIX . $userId);
    }

    public function putUser(int $userId, $userData, int $ttl = self::TTL_MEDIUM): bool
    {
        return $this->put(self::USER_PREFIX . $userId, $userData, $ttl);
    }

    public function forgetUser(int $userId): bool
    {
        return $this->forget(self::USER_PREFIX . $userId);
    }

    /**
     * 房间相关缓存
     */
    public function getRoom(string $roomId)
    {
        return $this->get(self::ROOM_PREFIX . $roomId);
    }

    public function putRoom(string $roomId, $roomData, int $ttl = self::TTL_MEDIUM): bool
    {
        return $this->put(self::ROOM_PREFIX . $roomId, $roomData, $ttl);
    }

    public function forgetRoom(string $roomId): bool
    {
        return $this->forget(self::ROOM_PREFIX . $roomId);
    }

    /**
     * 菜品相关缓存
     */
    public function getDishes()
    {
        return $this->get('dishes:all');
    }

    public function putDishes($dishes, int $ttl = self::TTL_LONG): bool
    {
        return $this->put('dishes:all', $dishes, $ttl);
    }

    public function getDish(int $dishId)
    {
        return $this->get(self::DISH_PREFIX . $dishId);
    }

    public function putDish(int $dishId, $dishData, int $ttl = self::TTL_LONG): bool
    {
        return $this->put(self::DISH_PREFIX . $dishId, $dishData, $ttl);
    }

    public function forgetDish(int $dishId): bool
    {
        return $this->forget(self::DISH_PREFIX . $dishId);
    }

    /**
     * 订单相关缓存
     */
    public function getRoomOrders(int $roomId)
    {
        return $this->get(self::ORDER_PREFIX . 'room:' . $roomId);
    }

    public function putRoomOrders(int $roomId, $orders, int $ttl = self::TTL_SHORT): bool
    {
        return $this->put(self::ORDER_PREFIX . 'room:' . $roomId, $orders, $ttl);
    }

    public function forgetRoomOrders(int $roomId): bool
    {
        return $this->forget(self::ORDER_PREFIX . 'room:' . $roomId);
    }

    /**
     * 用户订单缓存
     */
    public function getUserOrders(int $userId)
    {
        return $this->get(self::ORDER_PREFIX . 'user:' . $userId);
    }

    public function putUserOrders(int $userId, $orders, int $ttl = self::TTL_SHORT): bool
    {
        return $this->put(self::ORDER_PREFIX . 'user:' . $userId, $orders, $ttl);
    }

    public function forgetUserOrders(int $userId): bool
    {
        return $this->forget(self::ORDER_PREFIX . 'user:' . $userId);
    }


    /**
     * 统计信息缓存
     */
    public function getStats(string $type)
    {
        return $this->get('stats:' . $type);
    }

    public function putStats(string $type, $stats, int $ttl = self::TTL_MEDIUM): bool
    {
        return $this->put('stats:' . $type, $stats, $ttl);
    }

    /**
     * 使用Redis进行原子操作
     */
    public function increment(string $key, int $value = 1): int
    {
        return Redis::incrby($this->getKey($key), $value);
    }

    public function decrement(string $key, int $value = 1): int
    {
        return Redis::decrby($this->getKey($key), $value);
    }

    /**
     * 设置过期时间
     */
    public function expire(string $key, int $ttl): bool
    {
        return Redis::expire($this->getKey($key), $ttl);
    }

    /**
     * 获取缓存键
     */
    private function getKey(string $key): string
    {
        return self::PREFIX . $key;
    }

    /**
     * 批量删除缓存
     */
    public function forgetPattern(string $pattern): int
    {
        $keys = Redis::keys($this->getKey($pattern));
        if (empty($keys)) {
            return 0;
        }
        return Redis::del($keys);
    }

    /**
     * 获取缓存信息
     */
    public function getInfo(): array
    {
        return [
            'driver' => config('cache.default'),
            'prefix' => self::PREFIX,
            'memory_usage' => memory_get_usage(true),
            'peak_memory' => memory_get_peak_usage(true),
        ];
    }
}
